# WhiMai v2.0.0 - A Python interface for Whiskey Media sites
# Copyright (C) 2011 Anders Bugge
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# Contact Info
# E-Mail: whimais@gmail.com

# Thanks To
# http://www.whiskeymedia.com/
# http://www.giantbomb.com/
# http://www.comicvine.com/
# http://www.screened.com/
# http://www.tested.com/
# http://www.animevice.com/

import json
import urllib

list_limit = 100

url_list = "http://api.%(site)s/%(resource)s/?api_key=%(key)s&limit=%(lim)s&offset=%(off)s&%(extra)s&format=json"
url_detail = "http://api.%(site)s/%(resource)s/%(id)s/?api_key=%(key)s&format=json"

# List Whiskey Media sites
# id	: ID match number in array
# name	: Site name
# url	: Site URL address
# key	: Site API key
site_list = [
		{
			"id": 0,
			"name": "Giant Bomb",
			"url": "giantbomb.com",
			"key": ""
		 },
		 {
			"id": 1,
			"name": "Comic Vine",
			"url": "comicvine.com",
			"key": ""
		 },
		 {
			"id": 2,
			"name": "Screened",
			"url": "screened.com",
			"key": ""
		 },
		 {
			"id": 3,
			"name": "Tested",
			"url": "tested.com",
			"key": ""
		 },
		 {
			"id": 4,
			"name": "Anime Vice",
			"url": "animevice.com",
			"key": ""
		 }
		 ]

# Parser class
# Used for getting and error checking data
class Parser:
	def parseData(self):
		try:
			f = urllib.urlopen( self.url )
			self.data = f.read()
			self.status_code = json.loads(self.data)['status_code']
			
		except:
			print "Connection error"
			return False
		
		else:
			if int(self.status_code) != 1:
				error = str(json.loads(self.data)['error'])
				print "API Error: " + str(self.status_code) + ":" + error
				return False
			
			self.results = json.loads(self.data)['results']
			return True 

# BetailBsae class
# Used to request a Detail Resource 
class DetailBase(Parser):
	def __init__(self, site_id, resource):
		try:
			self.resource = resource
			self.site = site_list[ site_id ]['url']
			self.key = site_list[ site_id ]['key']
			
		except:
			print "UNKNOWN SITE ID (" + str(site_id) + ")"

	def getDetail(self, id):
		self.url = url_detail%{'site': self.site, 'resource': self.resource, 'id': id, 'key': self.key}
		ok = self.parseData()
		if ok != True:
			return None
		return self.results

# ListBase class
# Used to request a List Resource 
class ListBase(Parser):
	
	# site_id:	See site_list
	# resource:	See http://api.$site$.com/documentation/#resources
	# extra:	Added stuff list specific field_list, sorting and more (this varies depending on resources)
	def __init__(self, site_id, resource, extra=""):
		try:
			self.resource = resource
			self.site = site_list[ site_id ]['url']
			self.key = site_list[ site_id ]['key']
			self.extra = extra
		except:
			print "UNKNOWN SITE ID (" + str(site_id) + ")"
			
	def getSize(self):
		return len(self.results)
		
	def getTotalSize(self):
		return json.loads(self.data)['number_of_total_results']
	
	def getList(self, off, lim=20):
		self.url = url_list%{'site': self.site, 'resource': self.resource, 'lim': lim, 'off': off, 'extra': self.extra, 'key': self.key}
		ok = self.parseData()
		if ok != True:
			return None
		return self.results

	def getTotalList(self, off=0, req_limit=list_limit, cb=None):
		if cb != None:
			if cb( 0 ) == False:
				return None
		self.list_total = self.getList(off, req_limit)
		if self.list_total == None:
			return None
			
		# Check if more requests are needed
		self.list_size = self.getSize()
		self.list_size_total = self.getTotalSize()
		if self.list_size == self.list_size_total:
			if cb != None:
				if cb( 100 ) == False:
					return None
			return self.list_total
			
		# Get rest of results
		self.remaning = self.list_size_total / self.list_size
		if cb != None:
			if cb( 100 / (self.remaning+1) )  == False:
				return None
		for i in range(self.remaning):
			self.next_off = off + (i+1)*req_limit
			self.next_list = self.getList(self.next_off, req_limit)
			if self.next_list == None:
				return None
			self.list_total.extend( self.results )
			if cb != None:
				if cb( ( (i+2)*100 ) / (self.remaning+1) ) == False:
					return None
			
		return self.list_total
